package com.ia2011.project1.aima;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import com.ia2011.project1.debug.Debug;
import com.ia2011.project1.domain.Action;
import com.ia2011.project1.domain.Constants;
import com.ia2011.project1.domain.Spot;
import com.ia2011.project1.domain.TAction;
import com.ia2011.project1.domain.User;
import com.ia2011.project1.math.Utils;
import com.ia2011.project1.service.CarpoolingService;

import aima.search.framework.Successor;
import aima.search.framework.SuccessorFunction;
 
public class CSSuccessorFunction extends Debug implements SuccessorFunction {

	public List getSuccessors(Object obj) {
		
		ArrayList successors = new ArrayList();
		CarpoolingService carpoolingService = (CarpoolingService) obj; 
		
		for (int i=0; i<carpoolingService.getUsers().size(); i++) {
			for (int j=i+1; j<carpoolingService.getUsers().size(); j++) {
				User driver1 = carpoolingService.getUsers().get(i);
				User driver2 = carpoolingService.getUsers().get(j);
				if (driver1.isDriver() && driver2.isDriver()) {
										
					if ((driver1.getTransport().getPlan().size() - 2 > 0)
							&& (driver2.getTransport().getPlan().size() - 2 > 0)) { // driver1 & driver2 have some users to swap
						
						for(int k=1; k<driver1.getTransport().getPlan().size()-1; k++) { // not include 1-spot and last-spot (driver spots)
							for (int m=1; m<driver2.getTransport().getPlan().size()-1; m++) { // the same ^^^
								
								CarpoolingService newCarpoolingService = new CarpoolingService(carpoolingService);
								
								User newDriver1 = newCarpoolingService.getUsers().get(i);
								User newDriver2 = newCarpoolingService.getUsers().get(j);
								
								Spot spot1 = newDriver1.getTransport().getPlan().get(k);
								Spot spot2 = newDriver2.getTransport().getPlan().get(m);
								if (spot1.getAction().getType() == TAction.PICK_USER
										&& spot2.getAction().getType() == TAction.PICK_USER) {
									
//									info("spot1 userId: "+spot1.getAction().getUserId()+" spot2 userId:"+spot2.getAction().getUserId()+" before swap");
									Point point = spot1.getCoord();
									TAction type = spot1.getAction().getType();
									Integer userId = spot1.getAction().getUserId();
									
									spot1.setCoord(new Point(spot2.getCoord()));
									spot1.setAction(new Action(spot2.getAction().getType(), spot2.getAction().getUserId()));
									for (Spot spot : newDriver1.getTransport().getPlan()) {
										if (spot.getAction().getUserId() == userId) {
											spot.getAction().setUserId(spot2.getAction().getUserId()); // put for DROP_USER action the same userId of 2nd user
										}
									}
									
									spot2.setCoord(new Point(point));
									spot2.setAction(new Action(type, userId));
									for (Spot spot : newDriver2.getTransport().getPlan()) {
										if (spot.getAction().getUserId() == spot1.getAction().getUserId()) {
											spot.getAction().setUserId(userId);
										}
									}
//									info("spot1 userId: "+spot1.getAction().getUserId()+" spot2 userId:"+spot2.getAction().getUserId()+" after swap");
								}
								
								successors.add(new Successor("swap(driver1Id:" + newDriver1.getId() 
										+ ", driver2Id:" + newDriver2.getId()
										+ ", Spot1UserId(now Spot2):" + spot2.getAction().getUserId()
										+ ", Spot2UserId(now Spot1):" + spot1.getAction().getUserId(),
										newCarpoolingService));
								
								info("driver1: "+driver1.getWholeDistance()+" time:"+Utils.getTime(driver1.getWholeDistance()));
								info("driver2: "+driver2.getWholeDistance()+" time:"+Utils.getTime(driver2.getWholeDistance()));
								
								
							}
						}
					}
					
					
					
					
	//				info("driverId: "+user.getId());
					
	//				if (user.getTransport().getPlanTime() > Constants.TOTAL_MINUTES) {
	////					info("driver time exceed "+user.getTransport().getPlanTime()+" > "+Constants.TOTAL_MINUTES);
	//					// start removing user
	//					
	//					CarpoolingService newCarpoolingService = new CarpoolingService(carpoolingService);
	//					newCarpoolingService.removePassengerFromDriver(user);
	//					
	//					successors.add(new Successor("RemovePassengerFromDriver", newCarpoolingService));
	//				} else {
	////					info("driver time OK "+user.getTransport().getPlanTime()+" <= "+Constants.TOTAL_MINUTES);
	//					// start adding user
	//					
	//					CarpoolingService newCarpoolingService = new CarpoolingService(carpoolingService);
	//					newCarpoolingService.addPassengerToDriver(user);
	//					
	//					successors.add(new Successor("RemovePassengerFromDriver", newCarpoolingService));
	//				}
					
				}
			}
		}
		
		info("successors size="+successors.size());
		return successors;
	}

}
